//
// Created by hsj on 2024-1-8.
// Windows没有fork
// signal信号量
// void (*signal(int signo, void (*func)(int)))(int);
// signal函数在UNIX系列的不同操作系统中可能存在区别，但sigaction函数完全相同。
//

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#ifdef WIN32
//windows minGW64
//inet_ntop函数：_WIN32_WINNT
#ifdef _WIN32_WINNT
#undef _WIN32_WINNT
#endif
#define _WIN32_WINNT 0x0600
#include <winsock2.h>
#include <ws2tcpip.h>
//#pragma comment(lib,"ws2_32.lib")
#else
//linux  gcc
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/wait.h>
#include <signal.h>
#endif
void error_handling(char *message);

void timeout(int sig)
{
    if(sig==SIGALRM)
        puts("Time out!");
    alarm(2);//2 sec 之后触发SIGALRM信号
}


int main(int argc, char *argv[]){
    int i;
    /**
     * struct sigaction
       {
            void (*sa_handler)(int);
            sigset_t sa_mask;
            int sa_flags;
       }
        此结构体的sa_handler成 员保存信号处理函数的指针值(地址值)。
        sa_mask和sa_flags的所有位均初始化为0即可。这2个成员用于指定信号相关的选项和特性，而我们的目的主要是防止产生僵尸进程，故省略。

     */
    struct sigaction act;
    act.sa_handler=timeout ;//初始化函数句柄
    sigemptyset(&act.sa_mask);
    act.sa_flags=0;

    sigaction(SIGALRM, &act, 0);
    alarm(2);//2 sec 之后触发SIGALRM信号

    for(i=0; i<3; i++) {
        puts("wait...");
        //unsigned int sleep(unsigned int seconds);
        /**
         *  1)已经过了seconds所指定的墙上时钟时间
         *  2)发生信号时将唤醒由于调用sleep函数而进入阻塞状态的进程
         */
        sleep(100);//100 sec
    }

    return EXIT_SUCCESS;
}

void error_handling(char *message){
    fputs (message, stderr);
    fputc('\n', stderr);
    exit(1);
}
